﻿using System;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;

namespace UsersMutex
{
	class Program
	{
		#region Constants

		private const string MutexName = "Global\\{C2486853-7173-4BBC-B719-304DD719D4A6}";

		#endregion Constants

		#region Main

		static void Main()
		{
			try
			{
				Run();
			}
			catch (Exception e)
			{
				Console.WriteLine(e);
				Console.ReadKey();
			}
		}

		#endregion Main

		#region Helpers

		private static Mutex GetMutex()
		{
			var mutex = new Mutex(true, MutexName);
			var allowEveryoneRule = new MutexAccessRule(
				new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
			var securitySettings = new MutexSecurity();
			securitySettings.AddAccessRule(allowEveryoneRule);
			mutex.SetAccessControl(securitySettings);

			return mutex;
		}

		private static void Run()
		{
			Console.WriteLine("Creating initially owned mutex");
			var mutex = GetMutex();
			Console.WriteLine("Waiting for mutex for 3 seconds");
			var result = mutex.WaitOne(3000, true);
			Console.WriteLine(
				result
					? "No other apps. Press any key to close"
					: "Other apps running. Press any key to close.");
			Console.ReadKey();
		}

		#endregion Helpers
	}
}
